package com.typingtutor.ui.compose;

import com.typingtutor.dto.DocumentDAO;
import com.typingtutor.dto.FieldKeyInfoDAO;
import com.typingtutor.dto.FieldMappingDAO;
import com.typingtutor.dto.FolderDAO;
import com.typingtutor.model.*;
import com.typingtutor.util.ResourcesUtils;
import com.typingtutor.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.util.Collections;
import java.util.List;

/**
 * CollapsibleListPanel 封装了一个支持展开/折叠的配置列表，
 * 列表头部支持右键添加输入框，列表内容区支持显示多个输入项组件。
 */
@Slf4j
public class CollapsibleListPanel extends JPanel {
    private String listName;
    private JPanel headerPanel;   // 头部区域
    private JLabel titleLabel;
    private JButton toggleButton;
    private JPanel contentPanel;  // 输入项列表区域
    private boolean expanded = true;
    // 图标资源路径
    private final String EXPANDED_ICON_PATH = "/img/icon/expanded.png";
    private final String COLLAPSED_ICON_PATH = "/img/icon/collapsed.png";
    private final String ADD_ICON_PATH = "/img/icon/add.png";
    private final DefaultMutableTreeNode nodeType;
    private ButtonGroup radioButtonGroup;

    public CollapsibleListPanel(String listName, DefaultMutableTreeNode nodeType) {
        this.listName = listName;
        this.nodeType = nodeType;
        setLayout(new BorderLayout());
        radioButtonGroup = new ButtonGroup();
        initComponents();
    }

    private void initComponents() {
        // 头部区域：显示标题和切换按钮
        headerPanel = new JPanel(new BorderLayout());
        titleLabel = new JLabel(listName);

        ImageIcon icon = new ImageIcon(ResourcesUtils.getResourceFile(EXPANDED_ICON_PATH));
        Image image = icon.getImage().getScaledInstance(5, 5, Image.SCALE_SMOOTH);
        ImageIcon scaledIcon = new ImageIcon(image);
        toggleButton = new JButton(scaledIcon);

        ImageIcon addIcon = new ImageIcon(ResourcesUtils.getResourceFile(ADD_ICON_PATH));
        Image addImage = addIcon.getImage().getScaledInstance(11, 11, Image.SCALE_SMOOTH);
        ImageIcon addScaledIcon = new ImageIcon(addImage);
        JButton addButton = new JButton(addScaledIcon);

        // 创建一个新的面板来排列按钮
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        buttonPanel.add(addButton);
        buttonPanel.add(toggleButton);

        toggleButton.setMargin(new Insets(5, 5, 5, 5));
        toggleButton.setFocusable(false);
        toggleButton.addActionListener(e -> toggle());
        addButton.addActionListener(e -> {
            if (nodeType instanceof Folder) {
                addRule(UUIDUtils.getUUID());
                List<RandomRule> randomRules = CollapsibleListPanel.getInputFieldValues(this, null);
                FolderDAO.getInstance().saveFolderConfiguration((Folder)nodeType, randomRules);
            }
            if (nodeType instanceof Document) {
                List<String> fieldNames = CustomOptionPane.showInputDialog(CollapsibleListPanel.this,
                        Collections.singletonList("显示字段名"), Collections.singletonList(true), "请输入输入框名称："
                , new Dimension(200, 150));
                if (CollectionUtils.isNotEmpty(fieldNames)) {
                    final String uuid = UUIDUtils.getUUID();
                    addInputField(fieldNames.get(0), uuid);
                    List<FieldKeyMappingRelation> relations = CollapsibleListPanel.getInputFieldValues(this, uuid);
                    DocumentDAO.getInstance().saveDocumentConfiguration((Document) nodeType, relations);
                }
            }
        });
        headerPanel.add(buttonPanel, BorderLayout.EAST);
        headerPanel.add(titleLabel, BorderLayout.CENTER);

        add(headerPanel, BorderLayout.NORTH);

        // 输入项列表区域：使用 BoxLayout 排列所有输入项
        contentPanel = new JPanel();
        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
        // 设置 JScrollPane 的边框为无边框
        add(contentPanel, BorderLayout.CENTER);

    }

    public void addRule(String uuid) {
        if (nodeType instanceof Folder) {
            addRadioButtonField(uuid, nodeType);
        }
    }

    /**
     * 切换展开/折叠状态
     */
    private void toggle() {
        expanded = !expanded;
        contentPanel.setVisible(expanded);
        ImageIcon expandedIcon = null;
        if (expanded) {
            expandedIcon = new ImageIcon(ResourcesUtils.getResourceFile(EXPANDED_ICON_PATH));
        } else {
            expandedIcon = new ImageIcon(ResourcesUtils.getResourceFile(COLLAPSED_ICON_PATH));
        }
        Image expandedImage = expandedIcon.getImage().getScaledInstance(5, 5, Image.SCALE_SMOOTH);
        ImageIcon expandedImageScaledIcon = new ImageIcon(expandedImage);
        toggleButton.setIcon(expandedImageScaledIcon);
        revalidate();
        repaint();
        // 通知父容器重新布局
        Component parent = getParent();
        while (parent != null) {
            parent.revalidate();
            parent.repaint();
            parent = parent.getParent();
        }
    }

    /**
     * 添加一个包含单选框的输入项到 contentPanel 中
     */
    public void addRadioButtonField(String uuid, DefaultMutableTreeNode node) {
        RadioButtonFieldPanel radioButtonFieldPanel = new RadioButtonFieldPanel(node, uuid,this, contentPanel, radioButtonGroup);
        // 设置输入项面板左对齐
        radioButtonFieldPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        contentPanel.add(radioButtonFieldPanel);
        contentPanel.revalidate();
        contentPanel.repaint();
    }

    public void loadRadioButtonField(String uuid, boolean isEnabled, DefaultMutableTreeNode node) {
        RadioButtonFieldPanel radioButtonFieldPanel = new RadioButtonFieldPanel(node, uuid,this, contentPanel, radioButtonGroup
        ,isEnabled);
        // 设置输入项面板左对齐
        radioButtonFieldPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        contentPanel.add(radioButtonFieldPanel);
        contentPanel.revalidate();
        contentPanel.repaint();
    }


    /**
     * 添加一个输入项到 contentPanel 中
     */
    public void addInputField(String fieldName, String uuid) {
        InputFieldPanel inputFieldPanel = new InputFieldPanel(fieldName, uuid);
        // 设置输入项面板左对齐
        inputFieldPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        contentPanel.add(inputFieldPanel);
        contentPanel.revalidate();
        contentPanel.repaint();
    }

    public void loadInputField(String fieldName, String fieldValue, String fieldMappingUUID, String fieldKeyUUID) {
        InputFieldPanel inputFieldPanel = new InputFieldPanel(fieldName, fieldMappingUUID, fieldValue
        , fieldKeyUUID);
        // 设置输入项面板左对齐
        inputFieldPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
        contentPanel.add(inputFieldPanel);
        contentPanel.revalidate();
        contentPanel.repaint();
    }


    /**
     * 获取 JLabel 内容和 JTextField 用户输入内容的静态方法
     * @param panel CollapsibleListPanel 实例
     * @return 包含 JLabel 内容和 JTextField 用户输入内容的 Map
     */
    public static <T> List<T> getInputFieldValues(CollapsibleListPanel panel, String UUID) {
        List<T> values = Lists.newArrayList();
        Component[] components = panel.contentPanel.getComponents();
        for (Component component : components) {
            if (component instanceof InputFieldPanel) {
                InputFieldPanel inputFieldPanel = (InputFieldPanel) component;
                String labelText = inputFieldPanel.getLabelText();
                String fieldText = inputFieldPanel.getFieldText();
                String fieldMappingUUID = inputFieldPanel.getFieldMappingUUIDLabelText();
                String fieldKeyUUID = inputFieldPanel.getFieldMappingUUIDLabelText();
                if (UUID.equals(fieldMappingUUID)) {
                    values.add((T)new FieldKeyMappingRelation(fieldMappingUUID, fieldKeyUUID
                            , new FieldKeyInfo(fieldKeyUUID, labelText, inputFieldPanel.isDisplay())
                            , new FieldMapping(fieldMappingUUID, fieldText, null)));
                }
            }
            if (component instanceof RadioButtonFieldPanel) {
                RadioButtonFieldPanel radioButtonFieldPanel = (RadioButtonFieldPanel) component;
                String uuid = radioButtonFieldPanel.getUuid();
                String randomRange = radioButtonFieldPanel.getRandomRangeValue();
                String operator = radioButtonFieldPanel.getOperatorValue();
                String matchField = radioButtonFieldPanel.getMatchFieldValue();
                values.add((T)new RandomRule(uuid, randomRange, operator, matchField, radioButtonFieldPanel.isRadioButtonSelected()));
            }
        }
        return values;
    }

    /**
     * InputFieldPanel 表示单个输入项组件，
     * 包含一个 JLabel（显示名称）、一个 JTextField 及一个删除按钮，
     * 同时支持右键删除。
     */
    class InputFieldPanel extends JPanel {
        private JTextField textField;
        private JLabel label;
        private JLabel fieldMappingUUIDLabel;
        private JLabel fieldKeyUUIDLabel;

        public InputFieldPanel(String fieldName, String fieldMappingUUID) {
            // 使用GridBagLayout实现精细对齐
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();

            // 创建用于接收 UUID 的隐藏 JLabel
            fieldMappingUUIDLabel = new JLabel(fieldMappingUUID);
            fieldMappingUUIDLabel.setVisible(false);

            // ---------------------- JLabel 标签列 ----------------------
            gbc.gridx = 2; // 第三列
            gbc.anchor = GridBagConstraints.WEST; // 左对齐

            // 固定标签宽度，确保多行对齐
            label = new JLabel(fieldName + ": ");
            label.setPreferredSize(new Dimension(120, 25)); // 统一宽度
            add(label, gbc);

            // ---------------------- JTextField 输入框列 ----------------------
            gbc.gridx = 3; // 第四列
            gbc.fill = GridBagConstraints.HORIZONTAL; // 水平填充
            gbc.weightx = 1.0; // 占据剩余水平空间

            textField = new JTextField();
            textField.setPreferredSize(new Dimension(150, 25));
            textField.setMargin(new Insets(0, 0, 0, 0));
            add(textField, gbc);

            // ---------------------- JButton 按钮列 ----------------------
            gbc.gridx = 4; // 第五列
            gbc.fill = GridBagConstraints.NONE; // 不扩展
            gbc.weightx = 0.0; // 不占用额外空间

            JButton deleteButton = new JButton("删除");
            deleteButton.addActionListener(e -> removeThis());
            add(deleteButton, gbc);
        }

        public InputFieldPanel(String fieldName, String fieldMappingUUID, String fieldValue
        , String fieldKeyUUID) {
            this(fieldName, fieldMappingUUID);
            textField.setText(fieldValue);
            fieldKeyUUIDLabel = new JLabel(fieldKeyUUID);
            fieldKeyUUIDLabel.setVisible(false);
        }

        public boolean isDisplay() {
            if (fieldKeyUUIDLabel == null) {
                return false;
            }
            String fieldKeyId = fieldKeyUUIDLabel.getText();
            if (fieldKeyId == null || fieldKeyId.isEmpty()) {
                return false;
            }
            FieldKeyInfo info = FieldKeyInfoDAO.getInstance().findAllFieldById(fieldKeyId);
            if (info == null) {
                return false;
            }
            return info.isDisplay();
        }

        public String getLabelText() {
            return label.getText().replace(": ", "");
        }

        public void setLabelText(String text) {
            label.setText(text);
        }

        public String getFieldMappingUUIDLabelText() {
            return fieldMappingUUIDLabel.getText();
        }

        public void setFieldMappingUUIDLabel(String text) {
            fieldMappingUUIDLabel.setText(text);
        }

        public String getFieldText() {
            return textField.getText();
        }

        public void setFieldText(String text) {
            textField.setText(text);
        }

        private void removeThis() {
            FieldMappingDAO.getInstance().deleteById(fieldMappingUUIDLabel.getText());
            Component[] components = contentPanel.getComponents();
            int index = -1;
            for (int i = 0; i < components.length; i++) {
                if (components[i] == this) {
                    index = i;
                    break;
                }
            }
            if (index != -1) {
                contentPanel.remove(index);
                // 移除对应的垂直间隔
                if (index + 1 < contentPanel.getComponentCount() && contentPanel.getComponent(index + 1) instanceof Box.Filler) {
                    contentPanel.remove(index + 1);
                }
                contentPanel.revalidate();
                contentPanel.repaint();
            }
        }
    }
}